<template>
  <div class="app-container">
    <el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-position="middle"
             label-width="100px" size="mini"
    >
      <el-form-item label="样本复份编号" prop="sampBackupCode">
        <el-input
          v-model="queryParams.sampBackupCode"
          clearable
          placeholder="请输入样本复份编号"
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="样本类型" prop="sampTypeId">
        <treeselect v-model="queryParams.sampTypeId" :normalizer="normalizerSampType" :options="sampleTypeOptions"
                    placeholder="请选择样本类型" style="width: 214px"
        />
      </el-form-item>
      <el-form-item label="样本组" prop="sampGroupId">
        <treeselect v-model="queryParams.sampGroupId" :normalizer="normalizerSampGroup" :options="sampleGroupOptions"
                    placeholder="请选择样本组" style="width: 214px"
        />
      </el-form-item>
      <el-form-item label="样本源名称" prop="sourceName">
        <el-input
          v-model="queryParams.sourceName"
          clearable
          placeholder="请输入样本源名称"
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="样本源类型" prop="sourceTypeId">
        <treeselect v-model="queryParams.sourceTypeId" :normalizer="normalizerSourceType" :options="sourceTypeOptions"
                    placeholder="请选择样本源类型" style="width: 214px"
        />
      </el-form-item>
      <el-form-item label="样本状态" prop="sampState">
        <el-select
          v-model="queryParams.sampState"
          clearable
          placeholder="样本状态"
          size="small"
          style="width: 214px"
        >
          <el-option
            v-for="dict in sampStateOptions"
            :key="dict.dictValue"
            :label="dict.dictLabel"
            :value="dict.dictValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="条码/二维码" prop="qrCode">
        <el-input
          v-model="queryParams.qrCode"
          clearable
          placeholder="样本条码/二维码"
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="采样时间" prop="samplingRange">
        <el-date-picker
          v-model="queryParams.samplingRange"
          :picker-options="pickerOptions"
          align="right"
          end-placeholder="结束日期"
          range-separator="至"
          size="small"
          start-placeholder="开始日期"
          type="datetimerange"
          value-format="yyyy-MM-dd HH:mm:ss"
        >
        </el-date-picker>
      </el-form-item>
      <el-form-item label="删除状态" prop="delFlag">
        <el-select
          v-model="queryParams.delFlag"
          clearable
          placeholder="删除状态"
          size="small"
          style="width: 100px"
        >
          <el-option label="已删除" value="1"></el-option>
          <el-option label="未删除" value="0"></el-option>
        </el-select>

      </el-form-item>
      <el-form-item>
        <el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
        <el-button icon="el-icon-cpu" size="mini" type="success" @click="refreshSampleCount">更新计数</el-button>
      </el-form-item>
    </el-form>

    <el-table v-loading="loading" :data="sampleList" max-height="668" size="small"
              @selection-change="handleSelectionChange"
    >
      <el-table-column align="center" type="selection" width="55"/>
      <el-table-column align="center" label="样本复份编号" min-width="100" prop="sampBackupCode"/>
      <el-table-column align="center" label="样本类型" prop="sampTypeName"/>
      <el-table-column align="center" label="样本源编号" prop="sampSourceCode"/>
      <el-table-column align="center" label="样本源名称" prop="sampSourceName"/>
      <el-table-column align="center" label="采样时间" prop="samplingTime">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.samplingTime, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column align="center" label="样本位置" prop="sampLocation" width="300"/>
      <el-table-column align="center" label="样本源类型" prop="sampSourceTypeName"/>
      <el-table-column align="center" label="样本组" prop="sampGroupName"/>
      <el-table-column align="center" label="样本量" prop="sampQuantity"/>
      <el-table-column align="center" label="样本单位" prop="sampUnit"/>
      <el-table-column :formatter="sampStateFormat" align="center" label="样本状态" prop="sampState"/>
      <el-table-column align="center" label="冻融次数" prop="sampFreezeThawCount"/>
      <el-table-column align="center" label="条码/二维码" prop="qrCode"/>
      <el-table-column align="center" class-name="small-padding fixed-width" label="操作">
        <template slot-scope="scope">
          <el-button
            v-hasPermi="['biobank:sample:edit']"
            icon="el-icon-edit"
            size="mini"
            type="text"
            @click="handleUpdate(scope.row)"
          >修改
          </el-button>
          <el-button
            v-if="scope.row.delFlag === '0'"
            v-hasPermi="['biobank:sample:remove']"
            icon="el-icon-delete"
            size="mini"
            type="text"
            @click="handleDelete(scope.row)"
          >删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :limit.sync="queryParams.pageSize"
      :page.sync="queryParams.pageNum"
      :total="total"
      @pagination="getList"
    />

    <!-- 修改样本复份 对话框 -->
    <el-dialog :title="title" :visible.sync="open" append-to-body width="500px">
      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
        <el-form-item label="样本复份编号" prop="sampBackupCode">
          <el-input v-model="form.sampBackupCode" placeholder="请输入样本复份编号"/>
        </el-form-item>
        <el-form-item label="样本类型" prop="sampTypeId">
          <treeselect v-model="form.sampTypeId" :normalizer="normalizerSampType" :options="sampleTypeOptions"
                      placeholder="请选择样本类型"
                      @select="sampleTypeSelect"
          />
        </el-form-item>
        <el-form-item label="样本状态" prop="sampState">
          <el-select
            v-model="form.sampState"
            :disabled="form.delFlag === '1'"
            clearable
            placeholder="样本状态"
            size="small"
            style="width: 100%"
          >
            <el-option
              v-for="dict in sampStateOptions"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="样本组" prop="sampGroupId">
          <treeselect v-model="form.sampGroupId" :clearable="false" :normalizer="normalizerSampGroup"
                      :options="sampleGroupOptions" placeholder="请选择样本组"
          />
        </el-form-item>
        <el-form-item label="样本量" prop="sampQuantity">
          <el-input v-model="form.sampQuantity" oninput="value=value.replace(/[^0-9.]/g,'')" placeholder="请输入样本量"/>
        </el-form-item>
        <el-form-item label="样本单位" prop="sampUnit">
          <el-input v-model="form.sampUnit" placeholder="请输入样本单位"/>
        </el-form-item>
        <el-form-item v-if="false" label="样本复份序号" prop="sampBackupSeq">
          <el-input v-model="form.sampBackupSeq" placeholder="请输入样本复份序号"/>
        </el-form-item>
        <el-form-item label="格式化位置" prop="sampLocation">
          <el-input v-model="form.sampLocation" :disabled="true" placeholder="请输入格式化位置"/>
        </el-form-item>
        <el-form-item label="冻融次数" prop="sampFreezeThawCount">
          <el-input-number v-model="form.sampFreezeThawCount" :min="0" controls-position="right"
                           oninput="value=value.replace(/[^0-9.]/g,'')" placeholder="请输入冻融次数"
          />
        </el-form-item>
        <el-form-item label="采样时间" prop="samplingTime">
          <el-date-picker v-model="form.samplingTime" clearable
                          placeholder="选择采样时间"
                          size="small"
                          type="datetime"
                          value-format="yyyy-MM-dd HH:mm:ss"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item label="条码/二维码" prop="qrCode">
          <el-input v-model="form.qrCode" placeholder="请输入条码/二维码"/>
        </el-form-item>
        <el-form-item label="冻存管类型" prop="tubeType">
          <el-select
            v-model="form.tubeType"
            clearable
            placeholder="冻存管类型"
            size="small"
            style="width: 100%"
          >
            <el-option
              v-for="dict in tubeTypeOptions"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getSample, listAllSample, updateSample } from '@/api/biobank/sample'
import { delSample } from '@/api/biobank/tube'
import { getSampleType, listSampleType } from '@/api/biobank/sampleType'
import { listSampleGroup } from '@/api/biobank/sampleGroup'
import { listSourceType } from '@/api/biobank/sourceType'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { calculateSampleCount } from '@/api/biobank/container'
import { hideLoading, showLoading } from '@/utils/loading'

export default {
  name: 'SampleCheck',
  components: {
    Treeselect
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组id
      ids: [],
      // 选中数组
      selectSamples: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 样本复份 表格数据
      sampleList: [],
      // 弹出层标题
      title: '',
      // 是否显示弹出层
      open: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        orderByColumn: 'createTime',
        isAsc: 'DESC',
        sampBackupCode: undefined,
        sampState: undefined,
        sampTypeId: undefined,
        sampGroupId: undefined,
        sourceName: undefined,
        sourceTypeId: undefined,
        samplingRange: undefined,
        showDeleted: 1,
        delFlag: '0'
      },
      // 样本类型 树选项
      sampleTypeOptions: [],
      // 样本组 树选项
      sampleGroupOptions: [],
      // 样本源类型 树选项
      sourceTypeOptions: [],
      // 样本状态
      sampStateOptions: [],
      // 随访状态
      followStateOptions: [],
      // 冻存管类型
      tubeTypeOptions: [],
      // 启用的打印标签模板
      activeLabelTemp: {},
      // 表单参数
      form: {},
      // 创建样本表单参数
      createForm: {},
      // 表单校验
      rules: {
        sampBackupCode: [{ required: true, trigger: 'blur', message: '样本复份编号不能为空' }, {
          max: 50,
          trigger: 'blur',
          message: '样本复份编号不能超过50个字符'
        }],
        sampTypeId: { required: true, trigger: 'change', message: '样本类型不能为空' },
        sampState: { required: true, trigger: 'change', message: '样本状态不能为空' },
        sampFreezeThawCount: { required: true, trigger: 'blur', message: '冻融次数不能为空' },
        tubeType: { required: true, trigger: 'change', message: '冻存管类型不能为空' }
      },
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick(picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }]
      }
    }
  },
  created() {
    this.getDicts('sample_state').then(response => {
      this.sampStateOptions = response.data
    })
    this.getList()
    this.getSampleTypeList()
    this.getSampleGroupList()
    this.getSourceTypeList()
    this.getDicts('follow_state').then(response => {
      this.followStateOptions = response.data
    })
    this.getDicts('tube_type').then(response => {
      this.tubeTypeOptions = response.data
    })
  },
  methods: {
    // 重新计算各个容器当前存储样本数
    refreshSampleCount() {
      showLoading()
      calculateSampleCount().then(response => {
        hideLoading()
        this.$message.success('更新当前存储样本计数成功')
      }, error => {
        hideLoading()
      })
    },
    /** 查询样本类型 列表 */
    getSampleTypeList() {
      listSampleType().then(response => {
        this.sampleTypeOptions = this.handleTree(response.data, 'sampTypeId', 'parentId')
      })
    },
    /** 转换样本类型 数据结构 */
    normalizerSampType(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampTypeId,
        label: node.sampTypeName,
        children: node.children
      }
    },
    /** 查询样本组 列表 */
    getSampleGroupList() {
      listSampleGroup(this.queryParams).then(response => {
        this.sampleGroupOptions = this.handleTree(response.data, 'sampGroupId', 'parentId')
      })
    },
    /** 转换样本组 数据结构 */
    normalizerSampGroup(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sampGroupId,
        label: node.sampGroupName,
        children: node.children
      }
    },
    /** 查询样本源类型 列表 */
    getSourceTypeList() {
      listSourceType(this.queryParams).then(response => {
        this.sourceTypeOptions = this.handleTree(response.data, 'sourceTypeId', 'parentId')
      })
    },
    /** 转换样本源类型 数据结构 */
    normalizerSourceType(node) {
      if (node.children && !node.children.length) {
        delete node.children
      }
      return {
        id: node.sourceTypeId,
        label: node.sourceTypeName,
        children: node.children
      }
    },
    /** 样本状态状态字典翻译 */
    sampStateFormat(row, column) {
      return this.selectDictLabel(this.sampStateOptions, row.sampState)
    },
    /** 查询样本复份 列表 */
    getList() {
      this.loading = true
      // listSample(this.queryParams).then(response => {
      //   this.sampleList = response.rows;
      //   this.total = response.total;
      //   this.loading = false;
      // });

      listAllSample(this.queryParams).then(response => {
        this.sampleList = response.rows
        this.total = response.total
        this.loading = false
      })
    },
    // 取消按钮
    cancel() {
      this.open = false
      this.reset()
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm('queryForm')
      this.handleQuery()
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.sampBackupId)
      this.selectSamples = selection
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    // 样本类型下拉框选择事件
    sampleTypeSelect(node, instanceId) {
      getSampleType(node.sampTypeId).then(response => {
        if (response.data) {
          this.$set(this.createForm, 'sampQuantity', response.data.sampTypeDefaultQuantity)
          this.createForm.sampUnit = response.data.sampTypeDefaultUnit
          this.createForm.sampBackupCount = response.data.sampTypeDefaultDuplqty
        }
      })
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset()
      const sampBackupId = row.sampBackupId || this.ids
      getSample(sampBackupId).then(response => {
        this.form = response.data
        this.open = true
        this.title = '修改样本复份 '
      })
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (valid) {
          // 若样本为已删除，则更新为未删除，样本状态设置为虚拟
          if (this.form.delFlag === '1') {
            this.form.delFlag = '0'
            this.form.sampState = '0'
          }
          updateSample(this.form).then(response => {
            this.msgSuccess('修改成功')
            this.open = false
            this.getList()
          })
        }
      })
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      const sampBackupIds = row.sampBackupId || this.ids
      this.$confirm('是否确认删除样本复份 编号为"' + sampBackupIds + '"的数据项?', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(function() {
        return delSample(sampBackupIds)
      }).then(() => {
        this.getList()
        this.msgSuccess('删除成功')
      })
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true
    },
    // 文件上传成功处理
    handleFileSuccess(response, file, fileList) {
      this.upload.open = false
      this.upload.isUploading = false
      this.$refs.upload.clearFiles()
      this.$alert(response.msg, '导入结果', { dangerouslyUseHTMLString: true })
      this.getList()
    },
    // 提交上传文件
    submitFileForm() {
      this.$refs.upload.submit()
    },
    // 表单重置
    reset() {
      this.form = {
        sampBackupId: undefined,
        sampId: undefined,
        sampBackupCode: undefined,
        sampState: undefined,
        sampQuantity: undefined,
        sampUnit: undefined,
        sampBackupSeq: undefined,
        sampLocation: undefined,
        sampFreezeThawCount: undefined,
        samplingTime: undefined,
        qrCode: undefined,
        tubeType: undefined,
        stockState: undefined,
        delFlag: undefined,
        createBy: undefined,
        createTime: undefined,
        updateBy: undefined,
        updateTime: undefined
      }
      this.resetForm('form')
    }
  }
}
</script>
